#include "UI\Controls\ControlMgr.h"

///////////////////////////////////////////////////////////
//        ///  //////  /        ///  ///////  ///        //
//  //////  /  //////  /  //////  /  ///////  /  //////////
//        ///  //////  /        ///  ///////  /  //////////
//  /////////  //////  /  //////  /  ///////  /  //////////
//  ///////////      ///        ///        /  ///        //
///////////////////////////////////////////////////////////

bool ShRp::UI::ControlMgr::Init()
{
	Debug("ControlMgr Initializing.\n");
	if(!Control::StaticInit())	{	Error("Control::StaticInit failed.\n");	return false;	}


	Log("ControlMgr Initialized.\n");
	return true;
}

void ShRp::UI::ControlMgr::Terminate()
{
	Debug("ControlMgr Terminating.\n");


	Log("ControlMgr Terminating.\n");
}

void ShRp::UI::ControlMgr::AddControl( Control* _Control )
{
	m_Controls.push_back(_Control);
	_Control->CreateHWND();
	m_HWNDs.insert(HWNDControlPair(_Control->GetHWND(), _Control));
}

LRESULT CALLBACK ShRp::UI::ControlMgr::HandleHWNDMessage( HWND _HWND, UINT _Message, WPARAM _WParam, LPARAM _LParam )
{
	//Log("Msg: _HWND = 0x%x, _Message = 0x%x, _WParam = 0x%x, _LParam = 0x%x.\n", _HWND, _Message, _WParam, _LParam);


	switch(_Message)
	{
	case WM_MOUSEMOVE:		{	Mouse::SetPos(int2(GET_X_LPARAM(_LParam), GET_Y_LPARAM(_LParam)));							}	break;

	case WM_LBUTTONDOWN:	{	Mouse::SetButtonState(MouseButton::Left, true);												}	break;
	case WM_MBUTTONDOWN:	{	Mouse::SetButtonState(MouseButton::Middle, true);											}	break;
	case WM_RBUTTONDOWN:	{	Mouse::SetButtonState(MouseButton::Right, true);											}	break;
	case WM_XBUTTONDOWN:	{	if(GET_XBUTTON_WPARAM (_WParam) == 1)	Mouse::SetButtonState(MouseButton::Mouse4, true);	
								else									Mouse::SetButtonState(MouseButton::Mouse5, true);	}	break;
	case WM_KEYDOWN:		// Same as WM_SYSKEYDOWN
	case WM_SYSKEYDOWN:		{	Keyboard::SetKeyState((Key::En)_WParam, true);												}	break;

	case WM_LBUTTONUP:		{	Mouse::SetButtonState(MouseButton::Left, false);											}	break;
	case WM_MBUTTONUP:		{	Mouse::SetButtonState(MouseButton::Middle, false);											}	break;
	case WM_RBUTTONUP:		{	Mouse::SetButtonState(MouseButton::Right, false);											}	break;
	case WM_XBUTTONUP:		{	if(GET_XBUTTON_WPARAM (_WParam) == 1)	Mouse::SetButtonState(MouseButton::Mouse4, false);	
								else									Mouse::SetButtonState(MouseButton::Mouse5, false);	}	break;
	case WM_KEYUP:			// Same as WM_SYSKEYUP
	case WM_SYSKEYUP:		{	Keyboard::SetKeyState((Key::En)_WParam, false);												}	break;
	}

	HWNDControlMap::iterator it = m_HWNDs.find(_HWND);
	if(it != m_HWNDs.end())
	{
		Control* ctrl = (it->second);
		// Window has been found.
		switch(_Message)
		{
		case WM_PAINT:			{	ctrl->HandleMessage(WindowsMessage::Paint);																		}	break;
		case WM_DESTROY:		{	ctrl->HandleMessage(WindowsMessage::Destroy);																	}	break;
		case WM_MOUSEMOVE:		{	ctrl->HandleMessage(WindowsMessage::MouseMove);																	}	break;

		case WM_LBUTTONDOWN:	{	ctrl->HandleMessage(WindowsMessage::MouseDown, MouseButton::Left);												}	break;
		case WM_MBUTTONDOWN:	{	ctrl->HandleMessage(WindowsMessage::MouseDown, MouseButton::Middle);											}	break;
		case WM_RBUTTONDOWN:	{	ctrl->HandleMessage(WindowsMessage::MouseDown, MouseButton::Right);												}	break;
		case WM_XBUTTONDOWN:	{	if(GET_XBUTTON_WPARAM (_WParam) == 1)	ctrl->HandleMessage(WindowsMessage::MouseDown, MouseButton::Mouse4);
									else									ctrl->HandleMessage(WindowsMessage::MouseDown, MouseButton::Mouse5);	}	break;

		case WM_LBUTTONUP:		{	ctrl->HandleMessage(WindowsMessage::MouseUp, MouseButton::Left);												}	break;
		case WM_MBUTTONUP:		{	ctrl->HandleMessage(WindowsMessage::MouseUp, MouseButton::Middle);												}	break;
		case WM_RBUTTONUP:		{	ctrl->HandleMessage(WindowsMessage::MouseUp, MouseButton::Right);												}	break;
		case WM_XBUTTONUP:		{	if(GET_XBUTTON_WPARAM (_WParam) == 1)	ctrl->HandleMessage(WindowsMessage::MouseUp, MouseButton::Mouse4);	
									else									ctrl->HandleMessage(WindowsMessage::MouseUp, MouseButton::Mouse5);		}	break;
//#error Repeat does not trigger
		case WM_KEYDOWN:		// Same as WM_SYSKEYDOWN
		case WM_SYSKEYDOWN:		{	if(GetPrevKeyState(_LParam))			ctrl->HandleMessage(WindowsMessage::KeyRepeat, (Key::En)_WParam);
									else									ctrl->HandleMessage(WindowsMessage::KeyDown, (Key::En)_WParam);			}	break;
		case WM_KEYUP:			// Same as WM_SYSKEYUP
		case WM_SYSKEYUP:		{	ctrl->HandleMessage(WindowsMessage::KeyUp, (Key::En)_WParam);													}	break;
			
		default:
			return DefWindowProc(_HWND, _Message, _WParam, _LParam);
		}
		return 0;
	}
	else
	{
		// Window has not been found, send to default message handler.
		return DefWindowProc(_HWND, _Message, _WParam, _LParam);
	}
	Error("Failure in message handling.\n");
}

////////////////////////////////////////////////////////////////
//      ///      ///  /  //////  ///    ///          /        //
//  ////  /  ////  /  /  //////  /  ////  /////  /////  ////////
//      ///      ///  ///  //  ///        /////  /////      ////
//  ///////  //  ///  ///  //  ///  ////  /////  /////  ////////
//  ///////  ////  /  /////  /////  ////  /////  /////        //
////////////////////////////////////////////////////////////////

ShRp::UI::ControlList ShRp::UI::ControlMgr::m_Controls;
ShRp::UI::HWNDControlMap ShRp::UI::ControlMgr::m_HWNDs;
